﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using JSC.Core;
using JSC.Portal.Services;
using JSC.Portal.Entities;
using JSC.Core.Data;
using NHibernate;
using JSC.Data.NHibernate;
using JSC.Portal.Web.Controls;
using JSC.Portal.Web.Helper;

namespace JSC.Portal.Web.Controllers
{
    [Authorize(Roles = "Administrator,SiteAdministrator")]
    [HandleError]
    public class PortalPagesController : ServicedController<IPortalPageService>
    {
        private IDao<Template> _templateDao;
        private IDao<Role> _roleDao;

        public PortalPagesController()
        {
            _templateDao = new CommonDao<Template>();
            _roleDao = new CommonDao<Role>();
        }

        public ActionResult Edit(int id)
        {
            PortalPage pp = Service.GetById(id, false);
            LoadSelectionLists(pp);
            return View("Edit", pp);
        }

        public ActionResult Index()
        {
            PortalSite ps = ControllerContext.CurrentUser().PortalSite;
            if (ps != null && ps.PortalPages.Count > 0)
                return Edit(ps.PortalPages[0].Id);
            else
                return CreatePage(ps.Id);
        }

        public ActionResult CreateChildPage(int id)
        {
            PortalPage pp = Service.GetNewChildPage(id);
            LoadSelectionLists(pp);
            return View("Edit", pp);
        }

        public ActionResult CreatePage(int id)
        {
            PortalPage pp = Service.GetNewPortalPageBySiteId(id);
            LoadSelectionLists(pp);
            return View("Edit", pp);
        }

        public ActionResult Delete(int id)
        {
            using (ITransaction trans = NHibernateSession.Current.BeginTransaction())
            {
                PortalPage pp = Service.GetById(id, false);
                pp.PortalSite.PortalPages.Remove(pp);
                Service.Delete(pp);
                trans.Commit();
                return RedirectToAction("List", ControllerNames.PORTALSITES_CONTROLLER);
            }
        }

        public ActionResult SaveOrUpdate(int id, int? parentid, int siteid, string name, string description, string language, bool showInNavigation,
            Template template, DateTime validfrom, DateTime? validtill, string metaKeywords, string metaDescription, int[] viewAllowedRoles,
            int[] editAllowedRoles, bool propagateToSections, bool propagateToChildPages)
        {
            using (ITransaction trans = NHibernateSession.Current.BeginTransaction())
            {
                PortalPage pp = Service.GetById(id, false, true);
                if (parentid.HasValue)
                    pp.Parent = Service.GetById(parentid.Value, false);
                pp.PortalSite = FacadeFactory.CreateFacade<IPortalSiteService>().GetById(siteid, false);
                pp.Name = name;
                pp.Description = description;
                pp.Language = language;
                pp.SetNewFriendlyUrl();
                pp.ShowInNavigation = showInNavigation;
                pp.Template = _templateDao.GetById(template.Id, false);
                pp.ValidFrom = validfrom;
                pp.ValidTill = validtill;
                pp.MetaKeywords = metaKeywords;
                pp.MetaDescription = metaDescription;
                SetPermissions(ref pp, viewAllowedRoles, editAllowedRoles);
                if (propagateToChildPages) 
                    Service.PropagatePermissionsToChildPages(pp, propagateToSections);
                if (propagateToSections)
                    Service.PropagatePermissionsToSections(pp);
                if (pp.IsNew)
                {
                    int max = -1;
                    if (pp.Parent != null && pp.Parent.ChildPages.Count > 0)
                        max = pp.Parent.ChildPages.Max(m => m.Position);
                    pp.Position = ++max;
                }
                pp.SetTrackedData(User.Identity as PortalUser);
                pp = Service.SaveOrUpdate(pp);
                trans.Commit();
                return RedirectToAction("Edit", new { id = pp.Id });
            }
        }

        public ActionResult Move(int id, MoveAction moveAction)
        {
            using (ITransaction trans = NHibernateSession.Current.BeginTransaction())
            {
                PortalPage pp = Service.GetById(id, false);
                Service.MovePortalPage(pp, moveAction);
                trans.Commit();
                return RedirectToAction("Edit", new { id = pp.Id });
            }
        }

        public JsonResult GetFriendlyUrl(int? parentid, string name)
        {

            PortalPage p = Service.GetById(-1, false, true);
            if (parentid.HasValue)
                p.Parent = Service.GetById(parentid.Value, false);
            p.Name = name;
            p.SetNewFriendlyUrl();
            return Json(new { FriendlyUrl = p.FriendlyURL });
        }

        private void SetPermissions(ref PortalPage portalPage, int[] viewAllowedRoles, int[] editAllowedRoles)
        {
            portalPage.PagePermissions.Clear();
            foreach (Role r in _roleDao.GetAll().OrderByDescending(r => r.Id))
            {
                PortalPagePermission ppp = new PortalPagePermission();
                ppp.Role = r;
                ppp.Page = portalPage;
                ppp.ViewAllowed = viewAllowedRoles.Contains<int>(r.Id);
                ppp.EditAllowed = editAllowedRoles.Contains<int>(r.Id);
                if (ppp.ViewAllowed || ppp.EditAllowed)
                    portalPage.PagePermissions.Add(ppp);
            }
        }

        private void LoadSelectionLists(PortalPage portalPage)
        {
            IList<Template> templates = _templateDao.GetAll();
            IList<Language> languages = Service.GetAvailableLanguages(portalPage);
            this.ViewData["Templates"] = new SelectList(templates, "Id", "Name", portalPage.Template == null ? string.Empty : portalPage.Template.Id.ToString());
            this.ViewData["Languages"] = new SelectList(languages, "Culture", "Description", portalPage.Language);
            this.ViewData["Permissions"] = GetPermissions(portalPage);
        }

        private IList<Permission> GetPermissions(PortalPage portalPage)
        {
            IList<Permission> permissions = new List<Permission>();
            var roles = _roleDao.GetAll().OrderByDescending(r => r.Id);
            foreach (Role r in roles)
            {
                PortalPagePermission ppp = new PortalPagePermission();
                ppp.Page = portalPage;
                ppp.Role = r;
                if (portalPage != null)
                {
                    foreach (PortalPagePermission ppp2 in portalPage.PagePermissions)
                    {
                        if (ppp.RoleId == ppp2.RoleId)
                        {
                            ppp.ViewAllowed = ppp2.ViewAllowed;
                            ppp.EditAllowed = ppp2.EditAllowed;
                        }
                    }
                }
                permissions.Add(ppp);
            }
            return permissions;
        }
    }
}
